home *** CD-ROM | disk | FTP | other *** search
- #!/bin/bash
- # $Id$
- #
- # input-device specific hotplug policy agent.
- #
- # This should handle 2.6.* input hotplugging,
- # with a consistent framework for adding device and driver
- # specific handling.
- #
- # Normally, adding a input device will modprobe handler(s) for
- # this device.
- #
- # Kernel input hotplug params include (not all of them may be available):
- #
- # ACTION=%s [add or remove]
- # PRODUCT=%x/%x/%x/%x
- # NAME=%s
- # PHYS=%s
- # EV=%lx
- # KEY=%lx %lx ...
- # REL=%lx
- # ABS=%lx %lx ...
- # MSC=%lx
- # LED=%lx
- # SND=%lx
- # FF=%lx %lx ...
- #
- : ${ACTION?Bad invocation: \$ACTION is not set}
-
- cd /etc/hotplug
- . ./hotplug.functions
-
- # generated by module-init-tools
- MAP_CURRENT=$MODULE_DIR/modules.inputmap
-
- # used for kernel drivers that don't show up in MAP_CURRENT
- # or to overwrite default from MAP_CURRENT
- #
- MAP_HANDMAP=$HOTPLUG_DIR/input.handmap
-
- # Each modules.inputmap format line corresponds to one entry in a
- # MODULE_DEVICE_TABLE(input,...) declaration in a kernel file.
- #
- matchBits=0
- i_bustype=0
- i_vendor=0
- i_product=0
- i_version=0
- i_evBits=0
-
- input_join_words ()
- {
- local name=$1; shift
- local tmp=$1; shift
- while [ "$#" -gt 0 ]; do
- tmp="$tmp:$1"; shift
- done
- eval $name=\$tmp
- }
-
- input_convert_vars ()
- {
- if [ "$PRODUCT" != "" ]; then
- set -- `IFS=/; echo $PRODUCT`
- i_bustype=$((0x$1))
- i_vendor=$((0x$2))
- i_product=$((0x$3))
- i_version=$((0x$4))
- fi
-
- if [ "$EV" != "" ]; then
- i_evBits=$((0x$EV))
- fi
-
- input_join_words i_keyBits $KEY
- # for a in $KEY; do i_keyBits="${i_keyBits:+$i_keyBits:}${a}"; done
- input_join_words i_relBits $REL
- input_join_words i_absBits $ABS
- input_join_words i_mscBits $MSC
- input_join_words i_ledBits $LED
- input_join_words i_sndBits $SND
- input_join_words i_ffBits $FF
- }
-
- INPUT_DEVICE_ID_MATCH_BUS=1
- INPUT_DEVICE_ID_MATCH_VENDOR=2
- INPUT_DEVICE_ID_MATCH_PRODUCT=4
- INPUT_DEVICE_ID_MATCH_VERSION=8
- INPUT_DEVICE_ID_MATCH_EVBIT=$((0x010))
- INPUT_DEVICE_ID_MATCH_KEYBIT=$((0x020))
- INPUT_DEVICE_ID_MATCH_RELBIT=$((0x040))
- INPUT_DEVICE_ID_MATCH_ABSBIT=$((0x080))
- INPUT_DEVICE_ID_MATCH_MSCBIT=$((0x100))
- INPUT_DEVICE_ID_MATCH_LEDBIT=$((0x200))
- INPUT_DEVICE_ID_MATCH_SNDBIT=$((0x400))
- INPUT_DEVICE_ID_MATCH_FFBIT=$((0x800))
-
-
- input_match_bits ()
- {
- local mod_bits=$1 dev_bits=$2
-
- mword=$((0x${mod_bits##*:}))
- dword=$((0x${dev_bits##*:}))
-
- while true; do
- if [ $(( $mword & $dword != $mword )) -eq 1 ]; then
- return 1
- fi
-
- mod_bits=${mod_bits%:*}
- dev_bits=${dev_bits%:*}
-
- case "$mod_bits-$dev_bits" in
- *:*-*:* )
- : continue
- ;;
- *:*-*|*-*:* )
- return 0
- ;;
- * )
- return 1
- ;;
- esac
- done
- }
-
- #
- # stdin is "modules.inputmap" syntax
- # on return, all matching modules were added to $DRIVERS
- #
- input_map_modules ()
- {
- local line module
- local relBits mscBits ledBits sndBits keyBits absBits ffBits
-
- while read line
- do
- # comments are lines that start with "#" ...
- # be careful, they still get parsed by bash!
- case "$line" in
- \#*|"") continue ;;
- esac
-
- set $line
-
- module=$1
- matchBits=$(($2))
-
- bustype=$(($3))
- vendor=$(($4))
- product=$(($5))
- vendor=$(($6))
-
- evBits=$(($7))
- keyBits=$8
- relBits=$(($9))
-
- shift 9
- absBits=$(($1))
- cbsBits=$(($2))
- ledBits=$(($3))
- sndBits=$(($4))
- ffBits=$(($5))
- driverInfo=$(($6))
-
- : checkmatch $module
-
- : bustype $bustype $i_bustype
- if [ $INPUT_DEVICE_ID_MATCH_BUS -eq $(( $matchBits & $INPUT_DEVICE_ID_MATCH_BUS )) ] &&
- [ $bustype -ne $i_bustype ]; then
- continue
- fi
-
- : vendor $vendor $i_vendor
- if [ $INPUT_DEVICE_ID_MATCH_VENDOR -eq $(( $matchBits & $INPUT_DEVICE_ID_MATCH_VENDOR )) ] &&
- [ $vendor -ne $i_vendor ]; then
- continue
- fi
-
- : product $product $i_product
- if [ $INPUT_DEVICE_ID_MATCH_PRODUCT -eq $(( $matchBits & $INPUT_DEVICE_ID_MATCH_PRODUCT )) ] &&
- [ $product -ne $i_product ]; then
- continue
- fi
-
- # version i_version $i_version < version $version
- if [ $INPUT_DEVICE_ID_MATCH_VERSION -eq $(( $matchBits & $INPUT_DEVICE_ID_MATCH_VERSION )) ] &&
- [ $version -ge $i_version ]; then
- continue
- fi
-
- : evBits $evBits $i_evBits
- if [ $INPUT_DEVICE_ID_MATCH_EVBIT -eq $(( $matchBits & $INPUT_DEVICE_ID_MATCH_EVBIT )) ] &&
- [ $evBits -ne $(( $evBits & $i_evBits)) ]; then
- continue
- fi
- : keyBits $keyBits $i_keyBits
- if [ $INPUT_DEVICE_ID_MATCH_KEYBIT -eq $(( $matchBits & $INPUT_DEVICE_ID_MATCH_KEYBIT )) ] &&
- input_match_bits "$keyBits" "$i_keyBits"; then
- continue
- fi
- : relBits $relBits $i_relBits
- if [ $INPUT_DEVICE_ID_MATCH_RELBIT -eq $(( $matchBits & $INPUT_DEVICE_ID_MATCH_RELBIT )) ] &&
- [ $relBits -ne $(( $relBits & $i_relBits)) ]; then
- continue
- fi
-
- : absBits $absBits $i_absBits
- if [ $INPUT_DEVICE_ID_MATCH_ABSBIT -eq $(( $matchBits & $INPUT_DEVICE_ID_MATCH_ABSBIT )) ] &&
- input_match_bits "$absBits" "$i_absBits"; then
- continue
- fi
-
- : mscBits $mscBits $i_mscBits
- if [ $INPUT_DEVICE_ID_MATCH_MSCBIT -eq $(( $matchBits & $INPUT_DEVICE_ID_MATCH_MSCBIT )) ] &&
- [ $mscBits -ne $(( $mscBits & $i_mscBits)) ]; then
- continue
- fi
-
- : ledBits $ledBits $_ledBits
- if [ $INPUT_DEVICE_ID_MATCH_LEDBIT -eq $(( $matchBits & $INPUT_DEVICE_ID_MATCH_LEDBIT )) ] &&
- input_match_bits "$ledBits" "$i_ledBits"; then
- continue
- fi
-
- : sndBits $sndBits $i_sndBits
- if [ $INPUT_DEVICE_ID_MATCH_SNDBIT -eq $(( $matchBits & $INPUT_DEVICE_ID_MATCH_SNDBIT )) ] &&
- [ $sndBits -ne $(( $sndBits & $i_sndBits)) ]; then
- continue
- fi
-
- : ffBits $ffBits $i_ffBits
- if [ $INPUT_DEVICE_ID_MATCH_FFBIT -eq $(( $matchBits & $INPUT_DEVICE_ID_MATCH_FFBIT )) ] &&
- input_match_bits "$ffBits" "$i_ffBits"; then
- continue
- fi
-
- : driverInfo $driverInfo
- if [ $matchBits -eq 0 -a $driverInfo -eq 0 ]; then
- continue
- fi
-
- # It was a match!
- case " $DRIVERS " in
- *" $module "* )
- : already found
- ;;
- * )
- DRIVERS="$module $DRIVERS"
- ;;
- esac
- : drivers $DRIVERS
- done
- }
-
- #
- # What to do with this INPUT hotplug event?
- #
- case $ACTION in
-
- add)
-
- # If hwup does initialize the device there is nothing more to do
- if [ -x /sbin/hwup ] && /sbin/hwup ${1:+$1-}devpath-$DEVPATH -o hotplug; then
- : nix
- else
-
- input_convert_vars
-
- FOUND=""
- LABEL="INPUT product $PRODUCT"
-
- # cope with special driver module configurations first. So we can
- # overwrite default settings in MAP_CURRENT
- if [ -r $MAP_HANDMAP ]; then
- load_drivers usb $MAP_HANDMAP "$LABEL"
- FOUND="$FOUND${DRIVERS:+ $DRIVERS}"
- fi
-
- if [ -r $MAP_CURRENT -a -z "$FOUND" ]; then
- load_drivers input $MAP_CURRENT "$LABEL"
- fi
-
- fi
-
- ;;
-
- remove)
-
- if [ -x /sbin/hwdown ] && /sbin/hwdown ${1:+$1-}devpath-$DEVPATH -o hotplug; then
- : nix
- fi
-
- ;;
-
- *)
- debug_mesg INPUT $ACTION event not supported
- exit 1
- ;;
-
- esac
-